package com.bigfans.catalogservice.service.category;

import com.bigfans.catalogservice.dao.CategoryDAO;
import com.bigfans.catalogservice.model.Category;
import com.bigfans.catalogservice.model.CategoryAttribute;
import com.bigfans.catalogservice.model.SpecOption;
import com.bigfans.framework.cache.MethodCache;
import com.bigfans.framework.dao.BaseServiceImpl;
import com.bigfans.framework.dao.BeanDecorator;
import com.bigfans.framework.event.ApplicationEventBus;
import com.bigfans.framework.utils.BeanUtils;
import com.bigfans.framework.utils.CollectionUtils;
import com.bigfans.framework.utils.StringHelper;
import com.bigfans.model.event.CategoryCreatedEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 商品类别服务类
 * 
 * @author lichong
 *
 */
@Service(CategoryServiceImpl.BEAN_NAME)
public class CategoryServiceImpl extends BaseServiceImpl<Category> implements CategoryService {

	public static final String BEAN_NAME = "categoryService";
	
	private CategoryDAO categoryDAO;

	@Autowired
	private ApplicationEventBus eventBus;

	@Autowired
	public CategoryServiceImpl(CategoryDAO categoryDAO) {
		super(categoryDAO);
		this.categoryDAO = categoryDAO;
	}

	@Override
	@Transactional
	public void create(Category category) throws Exception {
		super.create(category);
		CategoryCreatedEvent event = new CategoryCreatedEvent();
		BeanUtils.copyProperties(category , event);
		eventBus.publishEvent(event);
	}

	/**
	 * 填充所有子类目
	 * 
	 * @param catList
	 * @return
	 * @throws Exception
	 */
	private List<Category> populateTree(List<Category> catList) throws Exception {
		if (catList == null || catList.isEmpty()) {
			return catList;
		}
		List<Category> subCatList = null;
		for (Category category : catList) {
			subCatList = this.listSubCats(category.getId());
			category.setSubCats(subCatList);
		}
		this.populateTree(subCatList);
		return catList;
	}

	@Transactional(readOnly = true)
	public List<Category> listByLevel(int level) throws Exception {
		return this.listByLevel(level, false);
	}
	
	@Transactional(readOnly = true)
	public List<Category> listByLevel(int level , boolean recursive) throws Exception {
		List<Category> catList =  categoryDAO.listByLevel(level);
		if(!recursive){
			return catList;
		}
		return this.populateTree(catList);
	}
	

	@Override
	public List<Category> listSubCats(String pid) throws Exception {
		return this.listSubCats(pid, false);
	}

	@Override
	public List<Category> listSubCats(String pid , boolean recursive) throws Exception {
		List<Category> catList =  categoryDAO.listSub(pid);
		if(!recursive){
			return catList;
		}
		return this.populateTree(catList);
	}
	
	/**
	 * 查询当前类别的所有父类别
	 * @param categoryId
	 * @return
	 * @throws Exception
	 */
	public Category loadParents(String categoryId) throws Exception{
		Category example = new Category();
		example.setId(categoryId);
		Category category = new BeanDecorator().load(categoryId, Category.class);
		this.recursiveParents(category);
		return category;
	}
	
	/**
	 * 递归查询所有父级
	 * @param category
	 * @throws Exception
	 */
	public void recursiveParents(Category category) throws Exception{
		if(category != null && StringHelper.isNotEmpty(category.getParentId())){
			Category parent = this.load(category.getParentId());
			category.setParent(parent);
			this.recursiveParents(parent);
		}
	}
	
	@Override
	public List<String> listParentIds(String categoryId) throws Exception {
		List<String> parentIds = new ArrayList<String>();
		this.getParentId(parentIds, categoryId);
		return parentIds;
	}
	
	private void getParentId(List<String> ids ,String catId){
		String parentId = categoryDAO.getParentId(catId);
		if(parentId == null){
			return ;
		} else {
			this.getParentId(ids, parentId);
			ids.add(parentId);
		}
	}
	

	@Transactional
	public void create(Category example , List<CategoryAttribute> calist , List<SpecOption> specList) throws Exception {
		// 保存类别
		super.create(example);
		// 保存类别和属性的关联关系
		if(CollectionUtils.isNotEmpty(calist)){
			List<CategoryAttribute> targetCaList = new ArrayList<CategoryAttribute>();
			for (CategoryAttribute ca : calist) {
				if(ca.getAttrId() == null || "".equals(ca.getAttrId().trim())){
					continue;
				}
				ca.setCategoryId(example.getId());
				targetCaList.add(ca);
			}
			new BeanDecorator(targetCaList).batchInsert();
		}
		
		// 保存类别下的默认规格
		if(CollectionUtils.isNotEmpty(specList)){
			for (SpecOption cs : specList) {
				cs.setCategoryId(example.getId());
			}
			//specService.batchCreate(specList);
		}
	}
	
	@Transactional
	public void update(Category example , List<CategoryAttribute> calist , List<SpecOption> specList) throws Exception {
		super.update(example);
		// 删除现有的类别和属性的关联
		CategoryAttribute condition = new CategoryAttribute();
		condition.setCategoryId(example.getId());
		new BeanDecorator(condition).delete();
		// 保存类别和属性的关联关系
		if(CollectionUtils.isNotEmpty(calist)){
			List<CategoryAttribute> targetCaList = new ArrayList<CategoryAttribute>();
			for (CategoryAttribute ca : calist) {
				if(ca.getAttrId() == null || "".equals(ca.getAttrId().trim())){
					continue;
				}
				ca.setCategoryId(example.getId());
				targetCaList.add(ca);
			}
			new BeanDecorator(targetCaList).batchInsert();
		}
		
		if(CollectionUtils.isNotEmpty(specList)){
			// 删除现有的类别下的所有规格
			SpecOption specExample = new SpecOption();
			specExample.setCategoryId(example.getId());
			new BeanDecorator(specExample).delete();
			
			// 保存类别下的默认规格
			for (SpecOption cs : specList) {
				cs.setCategoryId(example.getId());
			}
			new BeanDecorator(specList).batchInsert();
		}
	}
	
	public List<Category> listWithHierarchy() throws Exception{
		List<Category> categoryHierachy = this.listByLevel(Category.LEVEL_TOP, true);
		List<Category> categoryResultList = new ArrayList<Category>();
		for (Category category : categoryHierachy) {
			this.showCategoryHierachy(category, "", categoryResultList);
		}
		return categoryResultList;
	}
	
	private void showCategoryHierachy(Category category , String namePrefix , List<Category> categoryResultList){
		categoryResultList.add(category);
		if(category.hasChild()){
			category.setName(namePrefix+category.getName());
			namePrefix += "－";
			List<Category> childs = category.getSubCats();
			for (Category child : childs) {
				this.showCategoryHierachy(child, namePrefix , categoryResultList);
			}
		}else{
			category.setName(namePrefix+category.getName());
		}
	}
	
	@Override
	@MethodCache(key="catNav")
	@Transactional(readOnly = true)
	public List<Category> getNavigatorTree() throws Exception {
		List<Category> level2 = categoryDAO.listByLevel(2);
		for(Category cat2 : level2){
			List<Category> level3 = categoryDAO.listLevel3(cat2.getId(), true);
			cat2.setSubCats(level3);
			// 查询类别下的推荐品牌
		}
		return level2;
	}

}
